from urllib.parse import urlencode, parse_qs
from django.contrib.auth import login
from django.shortcuts import render, redirect
from django.views import View
from QQLoginTool.QQtool import OAuthQQ
from django.http import JsonResponse, HttpResponseForbidden
from django.conf import settings
from django_redis import get_redis_connection
import requests
import json

from otherAuth.constants import *
from otherAuth.models import QQAuth, SinaAuth
from meiduo.utils.encrypt import *
from users.models import User
from meiduo.utils.response_code import *
from carts.utils import shopping_car_combine


class GetUrl(View):
    """q获取登陆url"""
    def get(self,request):
        """获取qq登陆"""
        state = request.GET.get("next","/")
        qq_auth = OAuthQQ(client_id=QQ_CLIENT_ID, client_secret=QQ_CLIENT_SECRET, redirect_uri=QQ_REDIRECT_URI, state=state)

        login_url = qq_auth.get_qq_url()
        return JsonResponse({"login_url":login_url})


class QQLogin(View):
    """qq登陆视图"""
    def get(self,request):
        data = request.GET
        code = data.get("code")
        state = data.get("state","/")
        if code is None:
            return render(request,"404.html")

        qq_auth = OAuthQQ(client_id=QQ_CLIENT_ID, client_secret=QQ_CLIENT_SECRET, redirect_uri=QQ_REDIRECT_URI,state=state)
        try:
            access_token = qq_auth.get_access_token(code=code)
            openid = qq_auth.get_open_id(access_token=access_token)
            # 连接第三方获取openid(唯一标识符)
        except:
            return render(request,"login.html",{"account_errmsg":"第三方登陆失败"})

        try:
            """已存在的老用户动作"""
            user_qq = QQAuth.objects.get(openid=openid)
            user = user_qq.User
            login(request,user)
            # 状态保持
            response = redirect(state)
            response.set_cookie("username",user.username,max_age=settings.SESSION_COOKIE_AGE )
            # 设置会话cookie  过期时长与session同步
            return response

        except QQAuth.DoesNotExist:
            """未绑定qq的用户"""
            openid_secret = encrypts(openid)
            # 对openid进行加密后传给前端
            return render(request,"oauth_callback.html",{"openid":openid_secret})

    def post(self,request):
        """未绑定用户绑定视图"""
        data_dirt = request.POST
        mobile = data_dirt.get("mobile")
        password = data_dirt.get("password")
        sms_code = data_dirt.get("sms_code")
        openid = data_dirt.get("openid")
        if all([mobile,password,sms_code,openid]) is False:
            return render(request,"oauth_callback.html",{"account_errmsg":"用户名、密码错误","sms_code_errmsg":"短信验证码错误"})

        # 判断验证码输入是否正确
        conn = get_redis_connection(alias="verification")
        sms_code_send = conn.get(mobile)
        if sms_code_send is None:
            return render(request,"oauth_callback.html",{"sms_code_errmsg":"短信验证码过期"})
        if sms_code_send.decode() != sms_code:
            return render(request,"oauth_callback.html",{"sms_code_errmsg":"短信验证码错误"})

        try:
            # 对openid解密
            openid = decrypts(openid)
        except:
            return render(request,"login.html",{"account_errmsg":"操作超时"})

        # 判断新老用户
        try:
            """老用户处理逻辑"""
            user = User.objects.get(phone_number=mobile)
            if not user.check_password(password):
                return render(request,"oauth_callback.html",{"account_errmsg":"用户名、密码错误"})

        except User.DoesNotExist:
            """新用户处理逻辑"""
            user = User.objects.create_user(username=mobile,password=password,phone_number=mobile)

        QQAuth.objects.create(openid=openid, user=user)
        # 数据库中保存信息，外键关联
        login(request, user)
        state = request.GET.get("state", "/")
        response = redirect(state)
        response.set_cookie("username", user.username, max_age=settings.SESSION_COOKIE_AGE)
        # 状态保持

        shopping_car_combine(request,response)   # 合并购物车
        return response


class GetSinaUrl(View):
    def get(self,request):
        # https: // api.weibo.com / oauth2 / authorize& redirect_uri = YOUR_REGISTERED_REDIRECT_URI

        url_data={
            "client_id":client_id,
            "response_type":"code",
            "redirect_uri":redirect_uri,
        }
        url = "https://api.weibo.com/oauth2/authorize"+"?"+urlencode(url_data)

        return JsonResponse({"login_url":url})


class SinaLogin(View):
    def get(self,request):
        code = request.GET.get("code")
        if not code:
            return HttpResponseForbidden("参数错误")

#https://api.weibo.com/oauth2/access_token
        # ?client_id=YOUR_CLIENT_ID&
        # client_secret=YOUR_CLIENT_SECRET&
        # grant_type=authorization_code&
        # redirect_uri=YOUR_REGISTERED_REDIRECT_URI&
        # code=CODE
        url_data = {
            "client_id": str(client_id),
            "client_secret": client_secret,
            "grant_type": "authorization_code",
            "redirect_uri": redirect_uri,
            "code": code,
        }
        url = "https://api.weibo.com/oauth2/access_token"+"?"+urlencode(url_data)
        data = json.dumps(url_data)
        try:
            response = requests.post(url,data=data,json=json)
            data = response.content
            data = json.loads(data)
        except:
            return render(request, "login.html", {"account_errmsg": "第三方登陆失败"})
        code = data.get('access_token', None)
        if not code:
            return render(request, "login.html", {"account_errmsg": "第三方登陆失败"})

        # 判断是否为老用户
        try:
            """已存在的老用户动作"""
            user_sina = SinaAuth.objects.get(code=code)
            user = user_sina.user
            login(request,user)
            # 状态保持
            response = redirect("/")
            response.set_cookie("username",user.username,max_age=settings.SESSION_COOKIE_AGE )
            # 设置会话cookie  过期时长与session同步
            return response

        except SinaAuth.DoesNotExist:
            """未绑定qq的用户"""
            code_secret = encrypts(code)
            # code进行加密后传给前端
            return render(request, "oauth_callback.html", {"openid": code_secret})

    def post(self, request):
        """未绑定用户绑定视图"""
        data_dirt = request.POST
        mobile = data_dirt.get("mobile")
        password = data_dirt.get("password")
        sms_code = data_dirt.get("sms_code")
        code = data_dirt.get("openid")
        if all([mobile, password, sms_code, code]) is False:
            return render(request, "oauth_callback.html", {"account_errmsg": "用户名、密码错误", "sms_code_errmsg": "短信验证码错误"})

        # 判断验证码输入是否正确
        conn = get_redis_connection(alias="verification")
        sms_code_send = conn.get(mobile)
        if sms_code_send is None:
            return render(request, "oauth_callback.html", {"sms_code_errmsg": "短信验证码过期"})
        if sms_code_send.decode() != sms_code:
            return render(request, "oauth_callback.html", {"sms_code_errmsg": "短信验证码错误"})

        try:
            # 对openid解密
            code = decrypts(code)
        except:
            return render(request, "login.html", {"account_errmsg": "操作超时"})

        # 判断新老用户
        try:
            """老用户处理逻辑"""
            user = User.objects.get(phone_number=mobile)
            if not user.check_password(password):
                return render(request, "oauth_callback.html", {"account_errmsg": "用户名、密码错误"})

        except User.DoesNotExist:
            """新用户处理逻辑"""
            user = User.objects.create_user(username=mobile, password=password, phone_number=mobile)

        SinaAuth.objects.create(code=code, user=user)
        # 数据库中保存信息，外键关联
        login(request, user)

        response = redirect("/")
        response.set_cookie("username", user.username, max_age=settings.SESSION_COOKIE_AGE)
        # 状态保持

        shopping_car_combine(request, response)  # 合并购物车
        return response
